﻿using CodeGeneratorBootstrap.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CodeGeneratorBootstrap.Util
{
    public class DataTypeMapper
    {
        public static string ForEntities(AttributeModel input)
        {
            string result = "";
            if (input.Pk)
            {
                result = primitiveDataType(input);
            }
            else
            {
                switch (input.DataType.Name)
                {
                    case "Pickup List":
                        result = input.Nullable ? "int?" : "int";
                        //result = "int?";
                        break;
                    case "Lookup Table":
                        result = input.Name;
                        break;
                    case "String":
                        result = primitiveDataType(input);
                        break;
                    case "Summary-Sum":
                    case "Summary-Count":
                        result = input.Nullable ? "decimal?" : "decimal";
                        break;
                    case "Summary-Min":
                    case "Summary-Max": switch (input.AttributeForSummary.DataType.Name)
                        {
                            case "DateTime":
                                result = input.Nullable ? "DateTime?" : "DateTime";
                                break;
                            default:
                                result = input.Nullable ? "decimal?" : "decimal";
                                break;
                        }
                        break;

                    case "GeoLocation":
                        result = "String";
                        break;

                    default:
                        result = primitiveDataType(input);
                        result = input.Nullable ? result + "?" : result;
                        break;
                }
            }
            return result;
        }

        public static string ForModels(AttributeModel input)
        {
            string result = "";

            if (input.Pk)
            {
                result = primitiveDataType(input);

            }
            else
            {
                switch (input.DataType.Name)
                {
                    case "Pickup List":
                    case "Lookup Table":
                        result = "int";
                        //result = input.Nullable ? result + "?" : result;
                        break;
                    case "String":
                        result = primitiveDataType(input);
                        break;
                    case "Summary-Sum":
                    case "Summary-Count":
                        result = input.Nullable ? "decimal?" : "decimal";
                        break;
                    case "Summary-Min":
                    case "Summary-Max": switch (input.AttributeForSummary.DataType.Name)
                        {
                            case "DateTime":
                                result = input.Nullable ? "DateTime?" : "DateTime";
                                break;
                            default:
                                result = input.Nullable ? "Decimal?" : "Decimal";
                                break;
                        }
                        break;
                    case "GeoLocation":
                        result = "String";
                        break;
                    default:
                        result = primitiveDataType(input);
                        result = input.Nullable ? result + "?" : result;
                        break;
                }
            }
            return result;
        }

        // Start add for summary field
        public static string ForSummaryField(AttributeModel input)
        {
            string result = "";

            switch (input.DataType.Name)
            {
                case "Summary-Sum":
                    result = "Decimal";
                    break;
                case "Summary-Count":
                    result = "Int64";
                    break;
                case "Summary-Min":
                case "Summary-Max": switch (input.AttributeForSummary.DataType.Name)
                    {
                        case "DateTime":
                            result = "DateTime";
                            break;
                        default:
                            result = "Decimal";
                            break;
                    }

                    break;
                default:
                    result = primitiveDataType(input);
                    result = input.Nullable ? result + "?" : result;
                    break;
            }

            return result;
        }
        // End add for summary field

        public static string ForSearchs(AttributeModel input)
        {
            string result = "";

            switch (input.DataType.Name)
            {

                case "String":
                    result = primitiveDataType(input);
                    break;
                default:
                    result = primitiveDataType(input);
                    result = result + "?";
                    break;
            }
            return result;
        }

        public static string DefaultValue(AttributeModel input)
        {
            string result;
            switch (input.DataType.Name)
            {
                case "Summary-Sum":
                case "Summary-Count":
                    result = "0";
                    break;
                case "Summary-Min":
                case "Summary-Max":
                    switch (input.AttributeForSummary.DataType.Name)
                    {
                        case "DateTime":
                            result = "DateTime.Now";
                            break;
                        default:
                            result = "0";
                            break;
                    }

                    break;
                case "Pickup List":
                case "Lookup Table":
                case "Master Detail":
                case "short":
                case "int":
                case "long":
                case "ushort":
                case "uint":
                case "ulong":
                case "decimal":
                case "double":
                case "float":
                    result = "0";
                    break;
                case "char":
                    result = "\'\'";
                    break;
                case "bool":
                    result = "false";
                    break;
                case "DateTime":
                    result = "DateTime.Now";
                    break;
                default:
                    result = "\"\"";
                    break;
            }
            return result;
        }

        public static Tuple<bool, string> IsPrimitiveDataType(AttributeModel input)
        {
            Tuple<bool, string> result;
            switch (input.DataType.Name)
            {
                case "short":
                case "int":
                case "long":
                case "ushort":
                case "uint":
                case "ulong":
                case "char":
                case "bool":
                case "decimal":
                case "double":
                case "float":
                case "string":
                case "String":
                case "DateTime":
                    result = new Tuple<bool, string>(true, primitiveDataType(input));
                    break;
                case "Summary-Sum":
                case "Summary-Max":
                case "Summary-Min":
                    result = new Tuple<bool, string>(true, "decimal");
                    break;
                case "Summary-Count":
                    result = new Tuple<bool, string>(true, "int");
                    break;
                case "GeoLocation":
                    result = new Tuple<bool, string>(true, "String");
                    break;
                default:
                    result = new Tuple<bool, string>(false, primitiveDataType(input));
                    break;
            }
            return result;
        }

        public static bool IsCheckDataType(String input)
        {
            switch (input)
            {
                case "short":
                case "int":
                case "long":
                case "ushort":
                case "uint":
                case "ulong":
                case "bool":
                case "decimal":
                case "double":
                case "float":
                    return true;
                default:
                    return false;
            }
        }

        public static String GetDataType(String gType)
        {
            switch (gType)
            {
                case "short":
                    return "Int16";
                case "int":
                    return "Int32";
                case "long":
                    return "Int64";
                case "ushort":
                    return "UInt16";
                case "uint":
                    return "UInt32";
                case "ulong":
                    return "UInt64";
                case "decimal":
                    return "Decimal";
                case "double":
                    return "Double";
                case "float":
                    return "Single";
                case "bool":
                    return "bool";
                default:
                    return "String";
            }
        }

        private static string primitiveDataType(AttributeModel input)
        {
            // Note just in case DataType in DB is not C#  primitive DataType
            return input.DataType.Name;
        }

        public static bool isNumericDataType(AttributeModel input)
        {
            switch (DataTypeMapper.ForModels(input).ToLower())
            {
                case "short":
                case "int":
                case "long":
                case "ushort":
                case "uint":
                case "ulong":
                case "bool":
                case "decimal":
                case "double":
                case "float":
                case "short?":
                case "int?":
                case "long?":
                case "ushort?":
                case "uint?":
                case "ulong?":
                case "bool?":
                case "decimal?":
                case "double?":
                case "float?":
                    return true;
                default:
                    return false;
            }
        }
    }
}
